const Vue = require("vue");
const express = require("express");
const fs = require("fs");
const { createBundleRenderer } = require("vue-server-renderer");
const setupDevServer = require("./build/setup-dev-server.js");
// 判断环境
const isPord = process.env.NODE_ENV === "production";

const server = express();

// express.static 处理的是物理磁盘中的文件
server.use("/dist", express.static("./dist"));

let renderer;
let onReady;
// 生产模式
if (isPord) {
    const serverBundle = require("./dist/vue-ssr-server-bundle.json");
    const template = fs.readFileSync("./index.template.html", "utf-8");
    const clientManifest = require("./dist/vue-ssr-client-manifest.json");

    renderer = createBundleRenderer(serverBundle, {
        template,
        clientManifest,
    });
} else {
    // 开发模式 -> 监视源代码的改动打包构建 -> 重新生成 Renderer 渲染器
    onReady = setupDevServer(server, (serverBundle, template, clientManifest) => {
        renderer = createBundleRenderer(serverBundle, {
            template,
            clientManifest,
        });
    });
}
// 将渲染函数抽出
const render = async (req, res) => {
    try {
        const html = await renderer.renderToString(
            // app,   // 这里无需传入一个应用程序，因为在执行 bundle 时已经自动创建过。
            {
                title: "搭建自己的ssr",
                meta: `<meta name="discription" content="ssr"></meta>`,
                url: req.url,
            }
        );
        res.setHeader("Content-Type", "text/html; charset=utf8");
        res.end(html);
    } catch (err) {
        res.status(500).end("ERROR");
    }
};

// 服务端路由设置为 * 匹配所有路由
server.get(
    "*",
    isPord
        ? render
        : async (req, res) => {
              await onReady;
              // 在开发模式下 需要等待打包构建完成才能执行渲染函数
              render(req, res);
          }
);

server.listen(3000, () => {
    console.log("server runing...");
});
